home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet internetowy / Rozne / HTTrack 3.40-2 / httrack-3.40-2.exe / {app} / src_win / WinHTTrack / XSHBrowseForFolder.cpp < prev    next >
C/C++ Source or Header  |  2000-06-25  |  9KB  |  248 lines

  1. // ----------------------------------------------------------------------
  2. // 'extended' SHBrowseForFolder routine. ('New folder' button added)
  3. // Written by Xavier Roche, with the help of Gil Rosin, 
  4. // Todd Fast's routines from Pencilneck Software and other Usenet contributors.
  5. // Freeware, but no warranty!
  6. // 
  7. // Usage: (example)
  8. // CString path = XSHBrowseForFolder(this->m_hWnd,"Select path","c:\\") {
  9. //
  10. // To DO:
  11. //
  12. // #include "XSHBrowseForFolder.h"
  13. //
  14. // Then Add to the .rc file:
  15. //
  16. // IDD_NewFolder DIALOG DISCARDABLE  0, 0, 237, 46
  17. // STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
  18. // CAPTION "Create New Folder"
  19. // FONT 8, "MS Sans Serif"
  20. // BEGIN
  21. //     EDITTEXT        IDC_Folder,7,7,167,14,ES_AUTOHSCROLL
  22. //     DEFPUSHBUTTON   "OK",IDOK,180,7,50,14
  23. //     PUSHBUTTON      "Cancel",IDCANCEL,180,24,50,14
  24. // END
  25. // ----------------------------------------------------------------------
  26.  
  27. // TODO: Put in XSHBrowseForFolder.h your ressource definition
  28.  
  29. #include "stdafx.h"
  30. #include "shlobj.h"
  31. #include "XSHBrowseForFolder.h"
  32.  
  33. // our button ID
  34. int XSHBFF_button1 = -1;
  35.  
  36. // Main routine
  37. CString XSHBrowseForFolder(HWND hwnd,char* title,char* _path) {
  38.   char path[MAX_PATH]; path[0]='\0';
  39.  
  40.   // Remove the last slash bar
  41.   if (strlen(_path)>0)
  42.   if (_path[strlen(_path)-1]=='\\')
  43.     _path[strlen(_path)-1]='\0';
  44.  
  45.   // Get IMalloc Interface
  46.   LPMALLOC Mymal;
  47.   if (SHGetMalloc(&Mymal)!=NOERROR)
  48.     return path;
  49.   
  50.   // Build Root directory (My Computer)
  51.   LPITEMIDLIST Mylist;
  52.   if (SHGetSpecialFolderLocation(hwnd,CSIDL_DRIVES,&Mylist)==NOERROR) {
  53.  
  54.     // Convert _path into browse data
  55.     LPITEMIDLIST MyItemlist=XSHBFF_PathConvert(hwnd,_path);
  56.     
  57.     // Parameter structure for callback
  58.     char Thispath[MAX_PATH]; Thispath[0]='\0';
  59.     LONG CParam[2];
  60.     CParam[0]=(LONG) MyItemlist;
  61.     CParam[1]=(LONG) Thispath;
  62.     // Fill the BROWSEINFO structure
  63.     BROWSEINFO br;
  64.     br.hwndOwner=hwnd;       // hwnd
  65.     br.pidlRoot=NULL;        // root
  66.     br.pszDisplayName=path;  // buffer
  67.     br.lpszTitle=title;      // title
  68.     br.ulFlags=BIF_RETURNONLYFSDIRS;  // dir
  69.     br.lpfn=XSHBFF_CallbackProc;      // callback
  70.     br.lParam=(LONG) CParam;          // callback params
  71.     br.iImage=0;             // image
  72.     // And Call SHBrowseForFolder
  73.     LPITEMIDLIST UserList;
  74.     if ( (UserList = SHBrowseForFolder(&br)) != NULL) {
  75.       if (strlen(Thispath)==0) {  // No value in path
  76.         // Convert UserList to a string
  77.         if (SHGetPathFromIDList(UserList,path)==FALSE)
  78.           path[0]='\0';
  79.       } else
  80.         strcpy(path,Thispath);
  81.       Mymal->Free(UserList);
  82.     }
  83.     if (MyItemlist) Mymal->Free(MyItemlist);
  84.     Mymal->Free(Mylist);
  85.   }
  86.   return path;
  87. }
  88.  
  89. // XSHBFF_WndProc function type 
  90. typedef long (__stdcall * XSHBFF_WndProc_type)(HWND ,UINT ,WPARAM ,LPARAM);
  91.  
  92. // Window Routine
  93. long __stdcall XSHBFF_WndProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam) {
  94.   static char StringSelection[MAX_PATH]="";
  95.   static char* DirectReturnValue=NULL;
  96.   static XSHBFF_WndProc_type Ladr=DefDlgProc;
  97.   int wNotifyCode = HIWORD(wParam);  // notification code 
  98.   int wID = LOWORD(wParam);          // item, control, or accelerator identifier 
  99.   HWND hwndCtl = (HWND) lParam;      // handle of control
  100.   //
  101.   if (uMsg==WM_COMMAND) {            // WM_COMMAND message received
  102.     if (wID == XSHBFF_button1 ) {   // our button! 
  103.       if (strlen(StringSelection)>0) {  // there is a selection
  104.         CNewFolder f;
  105.         f.m_folder=StringSelection;
  106.         if (StringSelection[strlen(StringSelection)-1]!='\\')
  107.           f.m_folder+="\\";  // add a /
  108.         if (f.DoModal()==IDOK) {
  109.           char st[MAX_PATH];
  110.           strcpy(st,f.m_folder);
  111.           // Remove the last slash bar
  112.           if (strlen(st)>0)
  113.           if (st[strlen(st)-1]=='\\')
  114.             st[strlen(st)-1]='\0';
  115.           // create dir
  116.           if (_mkdir(st))              // error
  117.             AfxMessageBox("Folder already exists, or can not be created",MB_OK+MB_ICONEXCLAMATION);
  118.           else {    // Select the new path
  119.             if (DirectReturnValue) {
  120.               strcpy(DirectReturnValue,st);
  121.               wParam = (wParam & 0xFFFF0000) | XSHBrowseForFolder_OK;    // 'OK'
  122.               return Ladr(hwnd,uMsg,wParam,lParam); // former window routine
  123.             }
  124.           }
  125.         }
  126.       } else
  127.         AfxMessageBox("Please select a path first!",MB_OK);
  128.       return 0;
  129.     } else {
  130.       return Ladr(hwnd,uMsg,wParam,lParam); // former window routine
  131.     }
  132.   } else if (uMsg==XSHBrowseForFolder_SETSTRING) {  // received from our XSHBFF_CallbackProc routine
  133.     DirectReturnValue=(char*) lParam;
  134.     return 0;
  135.   } else if (uMsg==XSHBrowseForFolder_SETSTRING+1) {
  136.     Ladr = (XSHBFF_WndProc_type) lParam;  // store former address
  137.     return 0;
  138.   } else if (uMsg==BFFM_SELCHANGED) {  // received from our XSHBFF_CallbackProc routine
  139.     LPITEMIDLIST ItemSelection=(LPITEMIDLIST) lParam;  // catch the Item selection data
  140.     if (ItemSelection) {            // valid data (not null)
  141.       if (!SHGetPathFromIDList(ItemSelection,StringSelection)) {  // immedialtly converted into char string
  142.         StringSelection[0]='\0';    // clear, invalid
  143.       }
  144.     } else
  145.       StringSelection[0]='\0';      // clear, invalid
  146.     return 0;
  147.   } else {
  148.     return Ladr(hwnd,uMsg,wParam,lParam); // former window routine
  149.   }
  150. }
  151.  
  152. // Callback function
  153. int __stdcall XSHBFF_CallbackProc(HWND hwnd,UINT uMsg,LPARAM lParam,LPARAM lpData) {
  154.   if (uMsg==BFFM_SELCHANGED) {  // selection changed
  155.     XSHBFF_WndProc(hwnd,BFFM_SELCHANGED,0,lParam);
  156.   } 
  157.   else if (uMsg==BFFM_INITIALIZED) {  // init
  158. // DO NOT ADD BUTTON
  159. #if 0000
  160.     int x,y,w=0,h=0;
  161.     HWND ok = GetDlgItem(hwnd,XSHBrowseForFolder_OK);     // 'OK' button
  162.     if (ok) {
  163.       RECT rect;
  164.       GetWindowRect(ok,&rect);
  165.       
  166.       // screen coord -> client coord
  167.       POINT a,b;
  168.       a.x=rect.left; a.y=rect.top; b.x=rect.right; b.y=rect.bottom;
  169.       ScreenToClient(hwnd,&a); ScreenToClient(hwnd,&b);
  170.       rect.left=a.x; rect.top=a.y; rect.right=b.x; rect.bottom=b.y;
  171.       
  172.       // button's coordinates and size
  173.       x=rect.left;
  174.       y=rect.top;
  175.       w=rect.right-rect.left+1;
  176.       h=rect.bottom-rect.top+1;
  177.       x-=w+10;  // nice shift
  178.  
  179.       // Okay, then create the button
  180.       if (w*h != 0) {
  181.         // button's styles
  182.         int style = WS_CHILD | WS_CLIPSIBLINGS | BS_PUSHBUTTON | WS_TABSTOP | WS_VISIBLE;
  183.         // create button, parent=hwnd
  184.         HWND b = CreateWindow("BUTTON","New folder",style,x,y,w,h,hwnd,NULL,0,NULL);
  185.         LONG Ladr=NULL;
  186.         if (b!=NULL) {
  187.           // Send Font notification so that the font be the same as default font
  188.           HFONT hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
  189.           ::SendMessage(b, WM_SETFONT, (WPARAM) hFont, MAKELPARAM(1,0));
  190.           // Enable input
  191.           EnableWindow(b,true);
  192.           // Get the control ID of our button
  193.           XSHBFF_button1 = GetDlgCtrlID(b);
  194.           // Place our function
  195.           Ladr = SetWindowLong(hwnd,GWL_WNDPROC,(LONG) XSHBFF_WndProc);
  196.         }
  197.         
  198.         // initial selection
  199.         LONG* Param = (LONG*) lpData;
  200.         if (Param) {
  201.           // Send init dir
  202.           SendMessage(hwnd,BFFM_SETSELECTION,WPARAM(false),Param[0]);  // init dir
  203.           // Send string return address
  204.           XSHBFF_WndProc(hwnd,XSHBrowseForFolder_SETSTRING,0,Param[1]);             // return string
  205.           // Send former function address
  206.           if (Ladr) {
  207.             XSHBFF_WndProc(hwnd,XSHBrowseForFolder_SETSTRING+1,0,Ladr);             // return string
  208.           }
  209.         }
  210.       }
  211.     }
  212. #endif
  213.   }
  214.   return 0;
  215. }
  216.  
  217. // Convert a char* into a LPITEMIDLIST
  218. LPITEMIDLIST XSHBFF_PathConvert(HWND hwnd,char* _path) {
  219.   // Retrieves the IShellFolder interface for the desktop folder
  220.   LPSHELLFOLDER MyShellFolder;
  221.   if (SHGetDesktopFolder(&MyShellFolder) != NO_ERROR)
  222.     return NULL;
  223.   
  224.   // Initial path
  225.   ULONG pchEaten;
  226.   LPITEMIDLIST MyItemlist=NULL;
  227.   ULONG pdwAttributes;
  228.   if (strlen(_path)>0) {
  229.     char* lpszA = _path;
  230.     // -- Unicode conversion--
  231.     // we want to convert an MBCS string into lpszA    
  232.     int nLen = MultiByteToWideChar(CP_ACP, 0,lpszA, -1, NULL, NULL);
  233.     LPWSTR lpszW = new WCHAR[nLen];
  234.     MultiByteToWideChar(CP_ACP, 0, lpszA, -1, lpszW, nLen);
  235.     // parse string
  236.     MyShellFolder->ParseDisplayName(hwnd,NULL,lpszW,&pchEaten,&MyItemlist,&pdwAttributes);
  237.     // free the string
  238.     delete[] lpszW;
  239.     // -- Unicode conversion--    
  240.   }
  241.   return MyItemlist;
  242. }
  243.  
  244. // ----------------------------------------------------------------------
  245. // 'extended' SHBrowseForFolder routine. 'New folder' button added.
  246. // ----------------------------------------------------------------------
  247.  
  248.